/*
 * @ProjectName: 编程学习
 * @Copyright:   2019 HangZhou Ashe Dev, Ltd. All Right Reserved.
 * @address:     https://yiyuery.github.io/NoteBooks/
 * @date:        2020/2/23 10:49 下午
 * @description: 本内容仅限于编程技术学习使用，转发请注明出处.
 */
package com.yi.yier.boot.autoconfigure.codegenerator.internal;

import com.yi.yier.boot.autoconfigure.codegenerator.common.PropertiesLoader;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.MergeConstants;
import org.mybatis.generator.internal.DefaultCommentGenerator;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import static com.yi.yier.common.util.string.StringUtil.generatorRondomValue;
import static org.mybatis.generator.internal.util.StringUtility.isTrue;

/**
 * <p>
 *
 * </p>
 *
 * @author Yiyuery
 * @version V1.0.0
 * @date 2020/2/23 10:49 下午
 * @modificationHistory=========================逻辑或功能性重大变更记录
 * @modify By: {修改人}  2020/2/23
 * @modify reason: {方法名}:{原因}
 * ...
 */
public class XCommentGenerator  extends DefaultCommentGenerator {

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private boolean suppressSwagger;

    public XCommentGenerator() {
        this.suppressSwagger = isTrue(PropertiesLoader.getProps().getProperty("suppressSwagger"));
    }

    @Override
    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
        StringBuilder sb = new StringBuilder();

        innerClass.addJavaDocLine("/**"); //$NON-NLS-1$
        innerClass
                .addJavaDocLine("* This class was generated by Yier Code Generator."); //$NON-NLS-1$
        sb.append(introspectedTable.getFullyQualifiedTable());
        innerClass.addJavaDocLine(sb.toString());
        addJavadocTag(innerClass, markAsDoNotDelete);
        innerClass.addJavaDocLine("*/"); //$NON-NLS-1$
    }


    @Override
    public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        topLevelClass.addJavaDocLine("/**"); //$NON-NLS-1$
        topLevelClass
                .addJavaDocLine("* This class was generated by Yier Code Generator."); //$NON-NLS-1$
        StringBuilder sb = new StringBuilder();
        sb.append("* This class corresponds to the database table "); //$NON-NLS-1$
        sb.append(introspectedTable.getFullyQualifiedTable());
        topLevelClass.addJavaDocLine(sb.toString());
        topLevelClass.addJavaDocLine("*/"); //$NON-NLS-1$
    }

    /**
     * 自定义方法注释
     *
     * @param method
     * @param introspectedTable
     */
    @Override
    public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
        StringBuilder sb = new StringBuilder();
        method.addJavaDocLine("/**");

        sb.append("* ");
        if (method.isConstructor()) {
            sb.append(" 构造查询条件");
        }
        String method_name = method.getName();
        if ("setOrderByClause".equals(method_name)) {
            sb.append(" 设置排序字段");
        } else if ("setDistinct".equals(method_name)) {
            sb.append(" 设置过滤重复数据");
        } else if ("getOredCriteria".equals(method_name)) {
            sb.append(" 获取当前的查询条件实例");
        } else if ("isDistinct".equals(method_name)) {
            sb.append(" 是否过滤重复数据");
        } else if ("getOrderByClause".equals(method_name)) {
            sb.append(" 获取排序字段");
        } else if ("createCriteria".equals(method_name)) {
            sb.append(" 创建一个查询条件");
        } else if ("createCriteriaInternal".equals(method_name)) {
            sb.append(" 内部构建查询条件对象");
        } else if ("clear".equals(method_name)) {
            sb.append(" 清除查询条件");
        } else if ("countByExample".equals(method_name)) {
            sb.append(" 根据指定的条件获取数据库记录数");
        } else if ("deleteByExample".equals(method_name)) {
            sb.append(" 根据指定的条件删除数据库符合条件的记录");
        } else if ("deleteByPrimaryKey".equals(method_name)) {
            sb.append(" 根据主键删除数据库的记录");
        } else if ("insert".equals(method_name)) {
            sb.append(" 新写入数据库记录");
        } else if ("insertSelective".equals(method_name)) {
            sb.append(" 动态字段,写入数据库记录");
        } else if ("selectByExample".equals(method_name)) {
            sb.append(" 根据指定的条件查询符合条件的数据库记录");
        } else if ("selectByPrimaryKey".equals(method_name)) {
            sb.append(" 根据指定主键获取一条数据库记录");
        } else if ("updateByExampleSelective".equals(method_name)) {
            sb.append(" 动态根据指定的条件来更新符合条件的数据库记录");
        } else if ("updateByExample".equals(method_name)) {
            sb.append(" 根据指定的条件来更新符合条件的数据库记录");
        } else if ("updateByPrimaryKeySelective".equals(method_name)) {
            sb.append(" 动态字段,根据主键来更新符合条件的数据库记录");
        } else if ("updateByPrimaryKey".equals(method_name)) {
            sb.append(" 根据主键来更新符合条件的数据库记录");
        } else if ("equals".equals(method_name)) {
            sb.append(" 判断是否相等");
        } else if ("hashCode".equals(method_name)) {
            sb.append(" 生成唯一hashCode");
        } else if ("toString".equals(method_name)) {
            sb.append(" 生成toString方法");
        }
        sb.append(",");
        sb.append(introspectedTable.getFullyQualifiedTable());
        method.addJavaDocLine(sb.toString());

        final List<Parameter> parameterList = method.getParameters();
        if (!parameterList.isEmpty()) {
            method.addJavaDocLine("*");
            if ("or".equals(method_name)) {
                sb.append(" 增加或者的查询条件,用于构建或者查询");
            }
        } else {
            if ("or".equals(method_name)) {
                sb.append(" 创建一个新的或者查询条件");
            }
        }
        String paramterName;
        for (Parameter parameter : parameterList) {
            sb.setLength(0);
            sb.append("* @param ");
            paramterName = parameter.getName();
            sb.append(paramterName);
            if ("orderByClause".equals(paramterName)) {
                sb.append(" 排序字段");
            } else if ("distinct".equals(paramterName)) {
                sb.append(" 是否过滤重复数据");
            } else if ("criteria".equals(paramterName)) {
                sb.append(" 过滤条件实例");
            }
            method.addJavaDocLine(sb.toString());
        }
        method.addJavaDocLine("*/");
    }

    /**
     * 自定义Model内部变量 Swagger 注释
     *
     * @param field
     * @param introspectedTable
     */
    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        StringBuilder sb = new StringBuilder();
        if (suppressSwagger) {
            field.addJavaDocLine("/** ");
            sb.append(" * 字段注释：").append(introspectedColumn.getRemarks());
            field.addJavaDocLine(sb.toString());
            field.addJavaDocLine(" */");
            return;
        }
        if (introspectedColumn.getRemarks() != null) {
            sb.append("@ApiModelProperty(value=\"").append(introspectedColumn.getRemarks()).append("\",name=\"").append(introspectedColumn.getJavaProperty());
        }else{
            return;
        }
        switch (introspectedColumn.getJdbcTypeName()) {
            case "CHAR":
            case "LONGVARCHAR":
            case "VARCHAR":
                sb.append("\",example=\"")
                        .append(introspectedColumn.getJavaProperty())
                        .append("_")
                        .append(generatorRondomValue(String.class, 10))
                        .append("\",dataType=\"string\"");
                break;
            case "BIGINT":
                sb.append("\",example=\"")
                        .append(generatorRondomValue(Long.class, 10))
                        .append("\",dataType=\"long\"");
                break;
            case "DECIMAL":
            case "NUMERIC":
                sb.append("\",example=\"")
                        .append(generatorRondomValue(BigDecimal.class, 10))
                        .append("\",dataType=\"java.math.BigDecimal\"");
                break;
            case "INTEGER":
                sb.append("\",example=\"")
                        .append(generatorRondomValue(Integer.class, introspectedColumn.getLength()))
                        .append("\",dataType=\"int\"");
                break;
            case "BIT":
                sb.append("\",example=\"")
                        .append(generatorRondomValue(Boolean.class, 10))
                        .append("\",dataType=\"boolean\"");
                break;
            case "TINYINT":
                sb.append("\",example=\"")
                        .append(generatorRondomValue(Byte.class, 10))
                        .append("\",dataType=\"byte\"");
                break;
            case "SMALLINT":
                sb.append("\",example=\"")
                        .append(generatorRondomValue(Short.class, 10))
                        .append("\",dataType=\"short\"");
                break;
            case "REAL":
                sb.append("\",example=\"")
                        .append(generatorRondomValue(Float.class, 10))
                        .append("\",dataType=\"float\"");
                break;
            case "FLOAT":
            case "DOUBLE":
                sb.append("\",example=\"")
                        .append(generatorRondomValue(Double.class, 10))
                        .append("\",dataType=\"double\"");
                break;
            case "TIMESTAMP":
                sb.append("\",example=\"")
                        .append(sdf.format(new Date()))
                        .append("\",dataType=\"date\"");
                break;
            default:
                sb.append("\"");
                break;
        }
        if (!(introspectedColumn.isNullable())) {
            sb.append(", required=true)");
            field.addJavaDocLine(sb.toString());
        } else {
            sb.append(")");
            field.addJavaDocLine(sb.toString());
        }
    }

    @Override
    public void addComment(XmlElement xmlElement) {

        xmlElement.addElement(new TextElement("<!--")); //$NON-NLS-1$

        StringBuilder sb = new StringBuilder();
        sb.append(" WARNING - "); //$NON-NLS-1$
        sb.append(MergeConstants.NEW_ELEMENT_TAG);
        xmlElement.addElement(new TextElement(sb.toString()));
        xmlElement
                .addElement(new TextElement(
                        " This element is automatically generated by Yier Code Generator, do not modify.")); //$NON-NLS-1$
        String s = getDateString();
        if (s != null) {
            sb.setLength(0);
            sb.append(" This element was generated on "); //$NON-NLS-1$
            sb.append(s);
            sb.append('.');
            xmlElement.addElement(new TextElement(sb.toString()));
        }
        xmlElement.addElement(new TextElement("-->"));
    }
}